package com.xiaobai.myblog.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaobai.myblog.common.constant.Constants;
import com.xiaobai.myblog.common.lang.Result;
import com.xiaobai.myblog.common.redis.RedisCache;
import com.xiaobai.myblog.dto.LoginDto;
import com.xiaobai.myblog.entity.User;
import com.xiaobai.myblog.service.UserService;
import com.xiaobai.myblog.util.JwtUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
public class AccountController {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private RedisCache redisCache;

    @PostMapping("/login")
    public Result login(@Validated @RequestBody LoginDto loginDto, HttpServletResponse response) {
        String verifyKey = Constants.CAPTCHA_CODE_KEY + loginDto.getUuid();
        // 判断验证码
//        List<Object> cacheList = redisCache.getCacheList(verifyKey);
        String cacheVerify = (String)redisCache.getCacheObject(verifyKey);
        User user = userService.getOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));
        if (!cacheVerify.equals(loginDto.getVerificationCode())) {
            return Result.fail("验证码错误");
        }
        // 1.使用assert判断为null, 全局异常捕获
        Assert.notNull(user, "用户不存在");
        // 2.判断密码
        // 使用了hutool工具库SecureUtil
        if (!user.getPassword().equals(SecureUtil.md5(loginDto.getPassword()))) {
            return Result.fail("密码错误");
        }
        // 3.密码与账户验证通过, 生成jwt, 写入响应头
        String jwt = jwtUtils.generateToken(user.getId());
        response.setHeader("Authorization", jwt);
        // 列出Authorization可以作为响应的一部分暴露给外部
        response.setHeader("Access-Control-Expose-Headers", "Authorization");

        Map<Object, Object> data  = MapUtil.builder()
                .put("id", user.getId())
                .put("username", user.getUsername())
                .put("avatar", user.getAvatar())
                .put("email", user.getEmail()).map();
        // hutool工具库的工具库快速拼装map, 返回结果
        return Result.succ(data);
    }

    @GetMapping("/logout")
    @RequiresAuthentication
    public Result logout() {
        SecurityUtils.getSubject().logout();
        return Result.succ(null);
    }

    @PostMapping("/register")
    public Result login(@Validated @RequestBody User user) {

        // 判断是否存在数据库
        User dbUser = userService.getOne(new QueryWrapper<User>().eq("username", user.getUsername()));
        Assert.isNull(dbUser, "用户名已注册, 请输入其他用户名");

        // 处理初始设置
        user.setPassword(SecureUtil.md5(user.getPassword()));
        user.setStatus(0);
        user.setCreated(LocalDateTime.now());
        userService.save(user);
        return Result.succ(null);
    }
}
